<html>
<head>
    <title>Title</title>
</head>
<body>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>
<script type="text/javascript">
    var myModel;
    window.onload = function () {
        myModel = new Model;
        myModel.set("name", "name_id_abc");
    }
</script>
<input type="text" data-bind="name"/>
<span type="text" data-bind="name"/>
</body>
</html>

<script type="text/javascript">

    $(document).ready(function () {
        setTimeout(function () {
            myModel.set("name", "newName_id_def");
        }, 3000);
    });


    var pubsub = (function () {
        var _callbacks = {};
        var pubsub = {
            sub: function (name, callback) {
                if (!_callbacks.hasOwnProperty(name)) {
                    _callbacks[name] = [];
                }
                _callbacks[name].push(callback);
            },
            pub: function (name) {
                var args = Array.prototype.slice.call(arguments, 1)
                if (_callbacks.hasOwnProperty(name)) {
                    _callbacks[name].forEach(function (callback) {
                        callback.apply(this, args);
                    });
                }
            }
        }
        return pubsub;
    })();

    // listener capture view change event --> publish view.change event
    var changeHandler = function (event) {
        var target = event.target,
            propName = target.getAttribute('data-bind');
        if (propName && propName !== '') {
            pubsub.pub('model.change', propName, target.value);
        }
    }
    document.addEventListener('change', changeHandler, false);

    // view.change event --> change view
    pubsub.sub('view.change', function (propName, newVal) {
        var elements = document.querySelectorAll('[data-bind=' + propName + ']'),
            tagName;
        for (var i = 0, l = elements.length; i < l; i++) {
            tagName = elements[i].tagName.toLowerCase();
            if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {
                elements[i].value = newVal;
            } else {
                elements[i].innerHTML = newVal;
            }
        }
    });

    var Model = function () {
        var model = {
            props: {},
            set: function (propName, value) {
                this.props[propName] = value;
                // model change --> publish view.change event
                pubsub.pub('view.change', propName, value);
            },
            get: function (propName) {
                return this.props[propName];
            }
        }
        // model.change event --> change model data
        pubsub.sub('model.change', function (propName, newVal) {
            model.set(propName, newVal);
        });
        return model;
    }
</script>
